package com.whcoding.easyexcel.controller;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.fastjson.JSONObject;
import com.whcoding.easyexcel.strategy.CustomMergeStrategy;
import com.whcoding.easyexcel.util.LocalJsonUtil;
import com.whcoding.easyexcel.vo.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.SneakyThrows;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

/**
 * @program: spring-boot-learning
 * @description:EasyExcel导入导出测试Controller
 * @author: whcoding
 * @create: 2022-06-28 20:30
 **/
@Controller
@Api(tags = "EasyExcelController", description = "EasyExcel导入导出测试")
@RequestMapping("/easyExcel")
public class EasyExcelController {

    private static final Logger log = LoggerFactory.getLogger(EasyExcelController.class);

    /***
     *
     * http://localhost:3089/easyExcel/exportDeptList
     *
     * @SneakyThrows:https://blog.csdn.net/qq_22162093/article/details/115486647
     * @param response
     */
    @SneakyThrows(IOException.class)
    @ApiOperation(value = "导出部门列表Excel")
    @RequestMapping(value = "/exportDeptList", method = RequestMethod.GET)
    public void exportDeptList(HttpServletResponse response) {
        setExcelRespProp(response, "部门列表");
        List<OrmDeptExcelVO> deptList = LocalJsonUtil.getListFromJson("json/dept.json", OrmDeptExcelVO.class);
        EasyExcel.write(response.getOutputStream())
                .head(OrmDeptExcelVO.class)
                .excelType(ExcelTypeEnum.XLSX)
                .sheet("部门列表")
                .doWrite(deptList);
    }


    /**
     *
     * http://localhost:3089/easyExcel/importDeptList
     *
     * 注意：导入时候 ExcelVO 不要加注解@Accessors(chain = true) 否则会导致解析不到数据
     * @param file
     */
    @SneakyThrows
    @ApiOperation("从Excel导入部门列表")
    @RequestMapping(value = "/importDeptList", method = RequestMethod.POST)
    @ResponseBody
    public void importDeptList(@RequestPart("file") MultipartFile file) {
        List<OrmDeptExcelVO> deptExcelVOS = EasyExcel
                .read(file.getInputStream())
                .head(OrmDeptExcelVO.class)
                .sheet()
                .doReadSync();
        log.info("导入的Excel 转为JSON:{}", JSONObject.toJSONString(deptExcelVOS));
    }


    /**
     * 设置excel下载响应头属性
     */
    private void setExcelRespProp(HttpServletResponse response, String rawFileName) throws UnsupportedEncodingException {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode(rawFileName, "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
    }


    @SneakyThrows
    @ApiOperation(value = "导出订单列表Excel")
    @RequestMapping(value = "/exportOrderList", method = RequestMethod.GET)
    public void exportOrderList(HttpServletResponse response) {
        List<OrderVO> orderList = getOrderList();
        List<OrderDataExcelVO> orderDataExcelVOList = convertExcelList(orderList);
        setExcelRespProp(response, "订单列表");
        EasyExcel.write(response.getOutputStream())
                .head(OrderDataExcelVO.class)
                .registerWriteHandler(new CustomMergeStrategy(OrderDataExcelVO.class))
                .excelType(ExcelTypeEnum.XLSX)
                .sheet("订单列表")
                .doWrite(orderDataExcelVOList);
    }

    /**
     * OrderDataExcelVO 和OrderVO转换
     * @param orderList
     * @return
     */
    private List<OrderDataExcelVO> convertExcelList(List<OrderVO> orderList) {
        List<OrderDataExcelVO> result = new ArrayList<>();
        for (OrderVO order : orderList) {
            List<ProductVO> productList = order.getProductList();
            for (ProductVO product : productList) {
                OrderDataExcelVO orderDataExcelVO = new OrderDataExcelVO();
                BeanUtil.copyProperties(product, orderDataExcelVO);
                BeanUtil.copyProperties(order, orderDataExcelVO);
                result.add(orderDataExcelVO);
            }
        }
        return result;
    }

    /**
     * OrderVO 赋值
     * @return
     */
    private List<OrderVO> getOrderList() {
        List<OrderVO> orderList = LocalJsonUtil.getListFromJson("json/orders.json", OrderVO.class);
        List<ProductVO> productList = LocalJsonUtil.getListFromJson("json/products.json", ProductVO.class);
        List<OrmDeptExcelVO> deptExcelVOS = LocalJsonUtil.getListFromJson("json/dept.json", OrmDeptExcelVO.class);
        for (int i = 0; i < orderList.size(); i++) {
            OrderVO order = orderList.get(i);
            order.setDeptExcelVO(deptExcelVOS.get(i));
            order.setProductList(productList);
        }
        return orderList;
    }
}
